//
// Name :         Texture.h
// Description :  Header for CTexture, texture image class for OpenGL.
// Version :      See Texture.cpp
//

#if !defined(_TEXTURE_H)
#define _TEXTURE_H

#pragma once

#include <fstream>
#include <GL/gl.h>

//! Class to load and utilize texture files in OpenGL programs.

//! The CTexture class loads a BMP file into memory and allows it be
//! be easily used as a texture. Both regular texture mapping and Mipmapping
//! are supported by the model.
//! 
//! \par
//! Textures must be in BMP format with each dimensions a power of two.
//!
//! \par
//! Additional documentation is pending.

class CTexture  
{
public:
    CTexture();
    CTexture(const CTexture &p_img);
    virtual ~CTexture();

    //! Load a texture from a file
    /*! \param filename The filename as a wide (Unicode) character string. */
    bool LoadFile(const wchar_t *filename);

    //! Load a texture from a file.
    /* \param filename The filename as a char (8 bit) character string. */
    bool LoadFile(const char *filename);

    //! Returns an OpenGL texture name for this texture.
    /*! An OpenGL texture name is an integer. The first time this
        function is called the texture is created. Subsequent calls
        return the previously created texture name. */
    GLuint TexName();

    //! Returns an OpenGL texture name for this texture assuming mipmapping.
    /*! An OpenGL texture name is an integer. The first time this
        function is called the texture is created. Subsequent calls
        return the previously created texture name. The texture will
        be created with support for mipmapping. */
    GLuint MipTexName();

    void Fill(int r, int g, int b);
    void Set(int x, int y, int r, int g, int b);
    void SetSize(int p_x, int p_y);
    void SameSize(const CTexture &p_img);
    void Copy(const CTexture &p_img);
    BOOLEAN Empty() const {return m_width <= 0 || m_height <= 0;}
    CTexture &operator=(const CTexture &p_img);
    void SetAutoBmp(bool s) {m_autobmp = s;}

    BYTE *operator[](int i) {return m_image[i];}
    const BYTE *operator[](int i) const {return m_image[i];}
    BYTE *Row(int i) {return m_image[i];}
    const BYTE *Row(int i) const {return m_image[i];}

    int Width() const {return m_width;}
    int Height() const {return m_height;}
    BYTE *ImageBits() const {return m_image[0];}

private:
    bool m_mipinitialized;
    bool m_initialized;
    bool m_autobmp;         // Force suffix to .bmp, no matter what the actual type.
    GLuint m_texname;
    GLuint m_miptexname;
    bool ReadDIBFile(std::istream &file);
    bool ReadPPMFile(std::istream &file);
    int m_height;
    int m_width;
    BYTE ** m_image;
};

#endif 
